/* eslint-disable no-restricted-globals */
import {
  isArray,
  isMap,
  isObject,
  isSet,
  isString,
} from '../type-util/type-util';

/**
 * 生成唯一标识
 *
 * @export
 * @return {*}  {string}
 */
function S4() {
  // eslint-disable-next-line no-bitwise
  return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
}
export function createUUID(): string {
  return `${S4() + S4()}-${S4()}-${S4()}-${S4()}-${S4()}${S4()}${S4()}`;
}

/**
 * 设置cookie
 *
 * @static
 * @param {*} name 名称
 * @param {*} value 值
 * @param {*} day 过期天数
 * @param {boolean} [isDomain=false] 是否设置在主域下
 * @param {string} [path='/'] 默认归属路径
 * @memberof Util
 */
export function setCookie(
  name: string,
  value: string,
  day = 0,
  isDomain = false,
  path = '/',
): void {
  let domain = '';
  // 设置cookie到主域下
  if (isDomain) {
    // 是否为ip正则
    const regExpr =
      /^(25[0-5]|2[0-4]\d|[0-1]\d{2}|[1-9]?\d)\.(25[0-5]|2[0-4]\d|[0-1]\d{2}|[1-9]?\d)\.(25[0-5]|2[0-4]\d|[0-1]\d{2}|[1-9]?\d)\.(25[0-5]|2[0-4]\d|[0-1]\d{2}|[1-9]?\d)$/;
    // 为ip时忽略
    if (!regExpr.test(location.hostname)) {
      const host = location.hostname;
      if (host.indexOf('.') !== host.lastIndexOf('.')) {
        domain = `;domain=${host.substring(host.indexOf('.'), host.length)}`;
      }
    }
  }
  // 当设置的时间等于0时，不设置expires属性，cookie在浏览器关闭后删除
  if (day !== 0) {
    const expires = day * 24 * 60 * 60 * 1000;
    const date = new Date(new Date().getTime() + expires);
    document.cookie = `${name}=${escape(
      value,
    )};path=${path};expires=${date.toUTCString()}${domain}`;
  } else {
    document.cookie = `${name}=${escape(value)};path=${path}${domain}`;
  }
}

/**
 * 清除cookie
 *
 * @static
 * @param {string} cookieName
 * @param {boolean} [isDomain] 是否在主域下
 * @memberof Util
 */
export function clearCookie(cookieName: string, isDomain?: boolean): void {
  setCookie(cookieName, '', -1, isDomain);
}

/**
 * 获取cookie
 *
 * @static
 * @param {string} name
 * @return {*}  {*}
 * @memberof Util
 */
export function getCookie(name: string): string | null {
  const reg = new RegExp(`(^| )${name}=([^;]*)(;|$)`);
  const arr = document.cookie.match(reg);
  if (arr && arr.length > 1) {
    return unescape(arr[2]);
  }
  return null;
}

/**
 * 内部使用，是否为 null
 *
 * @author chitanda
 * @date 2022-09-07 23:09:09
 * @param {unknown} value
 * @return {*}  {boolean}
 */
function isNil(value: unknown): boolean {
  return value == null;
}

/**
 * 判断 对象、数组 以及字符串是否为空
 *
 * @author chitanda
 * @date 2022-09-07 23:09:02
 * @param {unknown} data
 * @return {*}  {boolean}
 */
function isEmpty(data: unknown): boolean {
  if (isArray(data) || isString(data)) {
    return (data as string | string[]).length === 0;
  }
  if (isObject(data)) {
    for (const key in data as any) {
      if (Object.prototype.hasOwnProperty.call(data, key)) {
        return false;
      }
    }
    return true;
  }
  if (isMap(data) || isSet(data)) {
    return (data as Map<unknown, unknown> | Set<unknown>).size === 0;
  }
  return data == null;
}

/**
 * 存在并且不等于空，支持数据类型对象、数组、字符串。例：[]、{}都算为空值。
 *
 * @export
 * @param {*} data
 * @return {*}  {boolean}
 */
export function notNilEmpty(data: unknown): boolean {
  if (!isNil(data) && !isEmpty(data)) {
    return true;
  }
  return false;
}

/**
 * 在当前类型中，不存在或者为空值。例：[]、{}都算为空值。
 *
 * @export
 * @param {*} data
 * @return {*}  {boolean}
 */
export function isNilOrEmpty(data: unknown): boolean {
  if (isNil(data) || isEmpty(data)) {
    return true;
  }
  return false;
}

/**
 * 默认生成排序值方法
 *
 * @export
 * @param {number} index 所在数据集下标
 * @return {*}  {number}
 */
export function generateOrderValue(index: number): number {
  return (index + 1) * 100;
}

/**
 * 获取query查询数据
 *
 * @author chitanda
 * @date 2021-05-18 11:05:34
 * @export
 * @param {string} variable 变量标识
 * @param {string} [query=location.search] 指定query，模型从 location.search 取
 * @return {*}  {*}
 */
export function getQueryVariable(
  variable: string,
  query: string = location.search,
): any {
  if (query.startsWith('?')) {
    query = query.substring(1);
  }
  const vars = query.split('&');
  for (let i = 0; i < vars.length; i++) {
    const pair = vars[i].split('=');
    // eslint-disable-next-line eqeqeq
    if (pair[0] == variable) {
      return pair[1];
    }
  }
  return false;
}

/**
 * 请求参数转义处理
 *
 * @author chitanda
 * @date 2021-05-31 16:05:48
 * @export
 * @param {Record<string, any>} opt
 * @return {*}  {string}
 */
export function formatHttpParams(opt: Record<string, any>): string {
  const params: any = {};
  const postData: string[] = [];
  Object.assign(params, opt);
  const keys: string[] = Object.keys(params);
  keys.forEach((key: string) => {
    const val: any = params[key];
    if (val instanceof Array || val instanceof Object) {
      postData.push(`${key}=${encodeURIComponent(JSON.stringify(val))}`);
    } else {
      postData.push(`${key}=${encodeURIComponent(val)}`);
    }
  });
  return postData.join('&');
}

/**
 * url最后补充query参数
 *
 * @author chitanda
 * @date 2021-05-31 16:05:55
 * @export
 * @param {string} url
 * @param {*} params
 * @return {*}  {string}
 */
export function setUrlQuery(url: string, params: any): string {
  const _strParams: string = formatHttpParams(params);
  if (url.endsWith('?')) {
    url = `${url}${_strParams}`;
  } else if (url.indexOf('?') !== -1 && url.endsWith('&')) {
    url = `${url}${_strParams}`;
  } else if (url.indexOf('?') !== -1 && !url.endsWith('&')) {
    url = `${url}&${_strParams}`;
  } else {
    url = `${url}?${_strParams}`;
  }
  return url;
}
